home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Files / BlitPixie / Sources / BlitPixieRotoZoomer.c < prev    next >
Encoding:
Text File  |  2000-10-06  |  19.6 KB  |  769 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. //    BlitPixieRotoZoomer
  3. //            a rotation/zoom blitter
  4. //
  5. //    written by Anders F Björklund <afb@algonet.se>
  6. //    © 1999 afb.
  7. ///--------------------------------------------------------------------------------------
  8.  
  9. #ifndef __BLITPIXIE__
  10. #include "BlitPixieHeader.h"
  11. #endif
  12.  
  13. #ifndef GENERATINGASM // do not include for asm file generation
  14.  
  15. static Boolean log2(long x,long *bit);
  16.  
  17. /*
  18.     trig tables : sintable[360], costable[360] in 16.16 fixed point format
  19.  
  20. */
  21.  
  22. static long trigtable[360 + 90] =
  23.           +0,   +1143,   +2287,   +3429,   +4571,   +5711,   +6850,   +7986,
  24.        +9120,  +10251,  +11380,  +12504,  +13625,  +14742,  +15854,  +16961,
  25.       +18063,  +19160,  +20251,  +21336,  +22414,  +23485,  +24549,  +25606,
  26.       +26655,  +27696,  +28728,  +29752,  +30766,  +31771,  +32767,  +33753,
  27.       +34728,  +35692,  +36646,  +37589,  +38520,  +39439,  +40347,  +41242,
  28.       +42125,  +42994,  +43851,  +44694,  +45524,  +46340,  +47141,  +47929,
  29.       +48702,  +49459,  +50202,  +50930,  +51642,  +52338,  +53018,  +53683,
  30.       +54330,  +54962,  +55576,  +56174,  +56754,  +57318,  +57863,  +58392,
  31.       +58902,  +59394,  +59869,  +60325,  +60763,  +61182,  +61582,  +61964,
  32.       +62327,  +62671,  +62996,  +63301,  +63588,  +63855,  +64102,  +64330,
  33.       +64539,  +64728,  +64897,  +65046,  +65175,  +65285,  +65375,  +65445,
  34.       +65495,  +65525,  +65534,  +65525,  +65495,  +65445,  +65375,  +65285,
  35.       +65175,  +65046,  +64897,  +64728,  +64539,  +64330,  +64102,  +63855,
  36.       +63588,  +63301,  +62996,  +62671,  +62327,  +61964,  +61582,  +61182,
  37.       +60762,  +60325,  +59869,  +59394,  +58902,  +58392,  +57863,  +57318,
  38.       +56754,  +56174,  +55576,  +54962,  +54330,  +53683,  +53018,  +52338,
  39.       +51642,  +50930,  +50202,  +49459,  +48702,  +47929,  +47141,  +46340,
  40.       +45524,  +44694,  +43851,  +42994,  +42125,  +41242,  +40347,  +39440,
  41.       +38520,  +37589,  +36646,  +35693,  +34728,  +33753,  +32767,  +31772,
  42.       +30766,  +29752,  +28728,  +27696,  +26655,  +25606,  +24550,  +23485,
  43.       +22414,  +21336,  +20251,  +19160,  +18064,  +16961,  +15854,  +14742,
  44.       +13625,  +12504,  +11380,  +10252,   +9120,   +7986,   +6850,   +5712,
  45.        +4571,   +3430,   +2287,   +1144,      +0,   -1143,   -2286,   -3429,
  46.        -4571,   -5711,   -6849,   -7986,   -9120,  -10251,  -11379,  -12504,
  47.       -13625,  -14741,  -15853,  -16961,  -18063,  -19160,  -20251,  -21335,
  48.       -22413,  -23485,  -24549,  -25606,  -26655,  -27695,  -28728,  -29751,
  49.       -30766,  -31771,  -32767,  -33752,  -34727,  -35692,  -36646,  -37588,
  50.       -38520,  -39439,  -40346,  -41242,  -42124,  -42994,  -43851,  -44694,
  51.       -45523,  -46339,  -47141,  -47928,  -48701,  -49459,  -50202,  -50929,
  52.       -51641,  -52338,  -53018,  -53682,  -54330,  -54961,  -55576,  -56174,
  53.       -56754,  -57317,  -57863,  -58391,  -58902,  -59394,  -59868,  -60324,
  54.       -60762,  -61181,  -61582,  -61964,  -62327,  -62671,  -62996,  -63301,
  55.       -63588,  -63855,  -64102,  -64330,  -64539,  -64728,  -64897,  -65046,
  56.       -65175,  -65285,  -65375,  -65445,  -65495,  -65525,  -65534,  -65525,
  57.       -65495,  -65445,  -65375,  -65285,  -65176,  -65046,  -64897,  -64728,
  58.       -64539,  -64331,  -64103,  -63855,  -63588,  -63302,  -62996,  -62671,
  59.       -62327,  -61964,  -61583,  -61182,  -60763,  -60325,  -59869,  -59395,
  60.       -58902,  -58392,  -57864,  -57318,  -56755,  -56175,  -55577,  -54962,
  61.       -54331,  -53683,  -53019,  -52339,  -51642,  -50930,  -50203,  -49460,
  62.       -48702,  -47930,  -47142,  -46341,  -45525,  -44695,  -43852,  -42995,
  63.       -42126,  -41243,  -40348,  -39440,  -38521,  -37590,  -36647,  -35693,
  64.       -34729,  -33754,  -32768,  -31773,  -30767,  -29753,  -28729,  -27697,
  65.       -26656,  -25607,  -24551,  -23486,  -22415,  -21337,  -20252,  -19161,
  66.       -18065,  -16963,  -15855,  -14743,  -13626,  -12506,  -11381,  -10253,
  67.        -9122,   -7988,   -6851,   -5713,   -4572,   -3431,   -2288,   -1145
  68.  
  69.             // table repeats, for the costable
  70.           +0,   +1143,   +2287,   +3429,   +4571,   +5711,   +6850,   +7986,
  71.        +9120,  +10251,  +11380,  +12504,  +13625,  +14742,  +15854,  +16961,
  72.       +18063,  +19160,  +20251,  +21336,  +22414,  +23485,  +24549,  +25606,
  73.       +26655,  +27696,  +28728,  +29752,  +30766,  +31771,  +32767,  +33753,
  74.       +34728,  +35692,  +36646,  +37589,  +38520,  +39439,  +40347,  +41242,
  75.       +42125,  +42994,  +43851,  +44694,  +45524,  +46340,  +47141,  +47929,
  76.       +48702,  +49459,  +50202,  +50930,  +51642,  +52338,  +53018,  +53683,
  77.       +54330,  +54962,  +55576,  +56174,  +56754,  +57318,  +57863,  +58392,
  78.       +58902,  +59394,  +59869,  +60325,  +60763,  +61182,  +61582,  +61964,
  79.       +62327,  +62671,  +62996,  +63301,  +63588,  +63855,  +64102,  +64330,
  80.       +64539,  +64728,  +64897,  +65046,  +65175,  +65285,  +65375,  +65445,
  81.       +65495,  +65525
  82. };
  83.  
  84. static long *sintable = &trigtable[0];
  85. static long *costable = &trigtable[90];
  86.  
  87.     /* texture delta values */
  88. #define horiz_delta_u    ( + cost )
  89. #define horiz_delta_v    ( + sint )
  90. #define vert_delta_u    ( - sint )
  91. #define vert_delta_v    ( + cost )
  92.     
  93.     
  94. /*
  95.         calculate the log base 2 of the argument,
  96.         i.e how many bits the number is shifted
  97.         
  98.         return value: is x a power of 2 at all ?
  99. */
  100.  
  101. static Boolean log2(long x,long *bit)
  102. {
  103.     long             i;
  104.     unsigned long    n;
  105.  
  106.     if (x <= 0)
  107.         return false;
  108.     
  109.     n = (unsigned long) x;
  110.      
  111.     for (i = 0; (n & 1) == 0; i++)
  112.     {
  113.         n >>= 1;
  114.     }
  115.     
  116.     if (n == 1)
  117.     {
  118.         *bit = i;        // 1 << i == x
  119.         return true;
  120.     }
  121.     else
  122.         return false;
  123. }
  124.  
  125. #pragma mark -
  126.  
  127. /*****************************************************************************************/
  128.  
  129. void BlitPixieRotoZoom8Bit(
  130.     unsigned char *source,
  131.     unsigned char *dest,
  132.     unsigned long srcBytes,
  133.     unsigned long dstBytes,
  134.     unsigned long width1,
  135.     unsigned long height1,        
  136.     unsigned long width2,
  137.     unsigned long height2,        
  138.     unsigned long angle,
  139.     unsigned long zoom )
  140. {
  141.     long            x,y;                            // loop variables
  142.     register unsigned char    *src,*dst;                // image pointers
  143.     unsigned long    stride;                            // add to go to next row
  144.     long            half_width,half_height;            // half of destination
  145.     long            start_u,start_v;                // starting texel
  146.     long            sint,cost;                        // sine and cosine
  147.     unsigned long    u,v,ul,vl;                        // texel, and fixed point texel
  148.     long            is_shift,shift_x,shift_y;        // shift instead of multiply
  149.  
  150.         /* normalize angle and zoom */
  151.     while (angle < 0)        angle += 360;
  152.     while (angle >= 360)    angle -= 360;
  153.  
  154.         /* get look-up values */
  155.     zoom >>= 8;
  156.     sint = (sintable[angle] * (long) zoom) >> 8;
  157.     cost = (costable[angle] * (long) zoom) >> 8;
  158.     
  159.     half_width = width2 >> 1;
  160.     half_height = height2 >> 1;
  161.  
  162.         /* get texture starting values (rotate around center) */
  163.     start_u = (width1 >> 1) << 16;
  164.     start_v = (height1 >> 1) << 16;
  165.     start_u -= cost * half_width - sint * half_height;
  166.     start_v -= sint * half_width + cost * half_height;
  167.     
  168.         /* init pointers & counters */
  169.     src = (unsigned char *) source;
  170.     dst = (unsigned char *) dest;
  171.     stride = (dstBytes - width2);
  172.     
  173.         /* is texture a multiple of 2 ? */
  174.     is_shift = log2(width1,&shift_x) && log2(height1,&shift_y);
  175.  
  176.     y = height2;
  177.     
  178.     if (is_shift)
  179.     {
  180.         do
  181.         {
  182.             ul = start_u;    vl = start_v;
  183.  
  184.             for (x = 0; x < width2; x++)
  185.             {    
  186.                 u = ul >> 16;    v = vl >> 16;    
  187.                 
  188.                 if (u >= 0 && u < width1 && v > 0 && v < height1 )
  189.                     *dst++ = src[(v << shift_x) + u];
  190.                 else
  191.                     ++dst;
  192.             
  193.                 ul += horiz_delta_u;    vl += horiz_delta_v;
  194.             }
  195.             
  196.             start_u += vert_delta_u;    start_v += vert_delta_v;
  197.             
  198.             dst += stride;
  199.         
  200.         } while (--y);
  201.     }
  202.     else
  203.     {
  204.         do
  205.         {
  206.             ul = start_u;    vl = start_v;
  207.  
  208.             for (x = 0; x < width2; x++)
  209.             {    
  210.                 u = ul >> 16;    v = vl >> 16;    
  211.                 
  212.                 if (u >= 0 && u < width1 && v >= 0 && v < height1 )
  213.                     *dst++ = src[(v * srcBytes) + u];
  214.                 else
  215.                     ++dst;
  216.             
  217.                 ul += horiz_delta_u;    vl += horiz_delta_v;
  218.             }
  219.             
  220.             start_u += vert_delta_u;    start_v += vert_delta_v;
  221.             
  222.             dst += stride;
  223.         
  224.         } while (--y);
  225.         
  226.     }
  227.  
  228. }
  229.  
  230. void BlitPixieMaskRotoZoom8Bit(
  231.     unsigned char *source,
  232.     unsigned char *dest,
  233.     unsigned char *maskAddr,
  234.     unsigned long srcBytes,
  235.     unsigned long dstBytes,
  236.     unsigned long width1,
  237.     unsigned long height1,        
  238.     unsigned long width2,
  239.     unsigned long height2,        
  240.     unsigned long angle,
  241.     unsigned long zoom )
  242. {
  243.     long            x,y;                            // loop variables
  244.     register unsigned char    *src,*dst,*mask;        // image pointers
  245.     unsigned long    stride;                            // add to go to next row
  246.     long            half_width,half_height;            // half of destination
  247.     long            start_u,start_v;                // starting texel
  248.     long            sint,cost;                        // sine and cosine
  249.     unsigned long    u,v,ul,vl;                        // texel, and fixed point texel
  250.     long            is_shift,shift_x,shift_y;        // shift instead of multiply
  251.  
  252.         /* normalize angle and zoom */
  253.     while (angle < 0)        angle += 360;
  254.     while (angle >= 360)    angle -= 360;
  255.  
  256.         /* get look-up values */
  257.     zoom >>= 8;
  258.     sint = (sintable[angle] * (long) zoom) >> 8;
  259.     cost = (costable[angle] * (long) zoom) >> 8;
  260.     
  261.     half_width = width2 >> 1;
  262.     half_height = height2 >> 1;
  263.  
  264.         /* get texture starting values (rotate around center) */
  265.     start_u = (width1 >> 1) << 16;
  266.     start_v = (height1 >> 1) << 16;
  267.     start_u -= cost * half_width - sint * half_height;
  268.     start_v -= sint * half_width + cost * half_height;
  269.     
  270.         /* init pointers & counters */
  271.     src = (unsigned char *) source;
  272.     mask = (unsigned char *) maskAddr;
  273.     dst = (unsigned char *) dest;
  274.     stride = (dstBytes - width2);
  275.     
  276.         /* is texture a multiple of 2 ? */
  277.     is_shift = log2(width1,&shift_x) && log2(height1,&shift_y);
  278.  
  279.     y = height2;
  280.     
  281.     if (is_shift)
  282.     {
  283.         do
  284.         {
  285.             ul = start_u;    vl = start_v;
  286.  
  287.             for (x = 0; x < width2; x++)
  288.             {    
  289.                 u = ul >> 16;    v = vl >> 16;    
  290.                 
  291.                 if (u >= 0 && u < width1 && v > 0 && v < height1 )
  292.                 {
  293.                     if ( mask[(v << shift_x) + u] == 0 )
  294.                         *dst++ = src[(v << shift_x) + u];
  295.                     else
  296.                         ++dst;
  297.                 }
  298.                 else
  299.                     ++dst;
  300.             
  301.                 ul += horiz_delta_u;    vl += horiz_delta_v;
  302.             }
  303.             
  304.             start_u += vert_delta_u;    start_v += vert_delta_v;
  305.             
  306.             dst += stride;
  307.         
  308.         } while (--y);
  309.     }
  310.     else
  311.     {
  312.         do
  313.         {
  314.             ul = start_u;    vl = start_v;
  315.  
  316.             for (x = 0; x < width2; x++)
  317.             {    
  318.                 u = ul >> 16;    v = vl >> 16;    
  319.                 
  320.                 if (u >= 0 && u < width1 && v >= 0 && v < height1 )
  321.                 {
  322.                     if ( mask[(v * srcBytes) + u] == 0 )
  323.                         *dst++ = src[(v * srcBytes) + u];
  324.                     else
  325.                         ++dst;
  326.                 }
  327.                 else
  328.                     ++dst;
  329.             
  330.                 ul += horiz_delta_u;    vl += horiz_delta_v;
  331.             }
  332.             
  333.             start_u += vert_delta_u;    start_v += vert_delta_v;
  334.             
  335.             dst += stride;
  336.         
  337.         } while (--y);
  338.     }
  339.  
  340. }
  341.  
  342. void BlitPixieRotoZoom16Bit(
  343.     unsigned short *source,
  344.     unsigned short *dest,
  345.     unsigned long srcBytes,
  346.     unsigned long dstBytes,
  347.     unsigned long width1,
  348.     unsigned long height1,        
  349.     unsigned long width2,
  350.     unsigned long height2,        
  351.     unsigned long angle,
  352.     unsigned long zoom )
  353. {
  354.     long            x,y;                            // loop variables
  355.     register unsigned short    *src,*dst;                // image pointers
  356.     unsigned long    stride;                            // add to go to next row
  357.     long            half_width,half_height;            // half of destination
  358.     long            start_u,start_v;                // starting texel
  359.     long            sint,cost;                        // sine and cosine
  360.     unsigned long    u,v,ul,vl;                        // texel, and fixed point texel
  361.     long            is_shift,shift_x,shift_y;        // shift instead of multiply
  362.  
  363.         /* normalize angle and zoom */
  364.     while (angle < 0)        angle += 360;
  365.     while (angle >= 360)    angle -= 360;
  366.  
  367.         /* get look-up values */
  368.     zoom >>= 8;
  369.     sint = (sintable[angle] * (long) zoom) >> 8;
  370.     cost = (costable[angle] * (long) zoom) >> 8;
  371.     
  372.     half_width = width2 >> 1;
  373.     half_height = height2 >> 1;
  374.  
  375.         /* get texture starting values (rotate around center) */
  376.     start_u = (width1 >> 1) << 16;
  377.     start_v = (height1 >> 1) << 16;
  378.     start_u -= cost * half_width - sint * half_height;
  379.     start_v -= sint * half_width + cost * half_height;
  380.     
  381.         /* init pointers & counters */
  382.     src = (unsigned short *) source;
  383.     dst = (unsigned short *) dest;
  384.     stride = (dstBytes - width2);
  385.     
  386.         /* is texture a multiple of 2 ? */
  387.     is_shift = log2(width1,&shift_x) && log2(height1,&shift_y);
  388.  
  389.     y = height2;
  390.     
  391.     if (is_shift)
  392.     {
  393.         do
  394.         {
  395.             ul = start_u;    vl = start_v;
  396.  
  397.             for (x = 0; x < width2; x++)
  398.             {    
  399.                 u = ul >> 16;    v = vl >> 16;    
  400.                 
  401.                 if (u >= 0 && u < width1 && v > 0 && v < height1 )
  402.                     *dst++ = src[(v << shift_x) + u];
  403.                 else
  404.                     ++dst;
  405.             
  406.                 ul += horiz_delta_u;    vl += horiz_delta_v;
  407.             }
  408.             
  409.             start_u += vert_delta_u;    start_v += vert_delta_v;
  410.             
  411.             dst += stride;
  412.         
  413.         } while (--y);
  414.     }
  415.     else
  416.     {
  417.         do
  418.         {
  419.             ul = start_u;    vl = start_v;
  420.  
  421.             for (x = 0; x < width2; x++)
  422.             {    
  423.                 u = ul >> 16;    v = vl >> 16;    
  424.                 
  425.                 if (u >= 0 && u < width1 && v >= 0 && v < height1 )
  426.                     *dst++ = src[(v * srcBytes) + u];
  427.                 else
  428.                     ++dst;
  429.             
  430.                 ul += horiz_delta_u;    vl += horiz_delta_v;
  431.             }
  432.             
  433.             start_u += vert_delta_u;    start_v += vert_delta_v;
  434.             
  435.             dst += stride;
  436.         
  437.         } while (--y);
  438.         
  439.     }
  440.  
  441. }
  442.  
  443. void BlitPixieMaskRotoZoom16Bit(
  444.     unsigned short *source,
  445.     unsigned short *dest,
  446.     unsigned short *maskAddr,
  447.     unsigned long srcBytes,
  448.     unsigned long dstBytes,
  449.     unsigned long width1,
  450.     unsigned long height1,        
  451.     unsigned long width2,
  452.     unsigned long height2,        
  453.     unsigned long angle,
  454.     unsigned long zoom )
  455. {
  456.     long            x,y;                            // loop variables
  457.     register unsigned short    *src,*dst,*mask;        // image pointers
  458.     unsigned long    stride;                            // add to go to next row
  459.     long            half_width,half_height;            // half of destination
  460.     long            start_u,start_v;                // starting texel
  461.     long            sint,cost;                        // sine and cosine
  462.     unsigned long    u,v,ul,vl;                        // texel, and fixed point texel
  463.     long            is_shift,shift_x,shift_y;        // shift instead of multiply
  464.  
  465.         /* normalize angle and zoom */
  466.     while (angle < 0)        angle += 360;
  467.     while (angle >= 360)    angle -= 360;
  468.  
  469.         /* get look-up values */
  470.     zoom >>= 8;
  471.     sint = (sintable[angle] * (long) zoom) >> 8;
  472.     cost = (costable[angle] * (long) zoom) >> 8;
  473.     
  474.     half_width = width2 >> 1;
  475.     half_height = height2 >> 1;
  476.  
  477.         /* get texture starting values (rotate around center) */
  478.     start_u = (width1 >> 1) << 16;
  479.     start_v = (height1 >> 1) << 16;
  480.     start_u -= cost * half_width - sint * half_height;
  481.     start_v -= sint * half_width + cost * half_height;
  482.     
  483.         /* init pointers & counters */
  484.     src = (unsigned short *) source;
  485.     mask = (unsigned short *) maskAddr;
  486.     dst = (unsigned short *) dest;
  487.     stride = (dstBytes - width2);
  488.     
  489.         /* is texture a multiple of 2 ? */
  490.     is_shift = log2(width1,&shift_x) && log2(height1,&shift_y);
  491.  
  492.     y = height2;
  493.     
  494.     if (is_shift)
  495.     {
  496.         do
  497.         {
  498.             ul = start_u;    vl = start_v;
  499.  
  500.             for (x = 0; x < width2; x++)
  501.             {    
  502.                 u = ul >> 16;    v = vl >> 16;    
  503.                 
  504.                 if (u >= 0 && u < width1 && v > 0 && v < height1 )
  505.                 {
  506.                     if ( mask[(v << shift_x) + u] == 0 )
  507.                         *dst++ = src[(v << shift_x) + u];
  508.                     else
  509.                         ++dst;
  510.                 }
  511.                 else
  512.                     ++dst;
  513.             
  514.                 ul += horiz_delta_u;    vl += horiz_delta_v;
  515.             }
  516.             
  517.             start_u += vert_delta_u;    start_v += vert_delta_v;
  518.             
  519.             dst += stride;
  520.         
  521.         } while (--y);
  522.     }
  523.     else
  524.     {
  525.         do
  526.         {
  527.             ul = start_u;    vl = start_v;
  528.  
  529.             for (x = 0; x < width2; x++)
  530.             {    
  531.                 u = ul >> 16;    v = vl >> 16;    
  532.                 
  533.                 if (u >= 0 && u < width1 && v >= 0 && v < height1 )
  534.                 {
  535.                     if ( mask[(v * srcBytes) + u] == 0 )
  536.                         *dst++ = src[(v * srcBytes) + u];
  537.                     else
  538.                         ++dst;
  539.                 }
  540.                 else
  541.                     ++dst;
  542.             
  543.                 ul += horiz_delta_u;    vl += horiz_delta_v;
  544.             }
  545.             
  546.             start_u += vert_delta_u;    start_v += vert_delta_v;
  547.             
  548.             dst += stride;
  549.         
  550.         } while (--y);
  551.     }
  552.  
  553. }
  554.  
  555. void BlitPixieRotoZoom32Bit(
  556.     unsigned long *source,
  557.     unsigned long *dest,
  558.     unsigned long srcBytes,
  559.     unsigned long dstBytes,
  560.     unsigned long width1,
  561.     unsigned long height1,        
  562.     unsigned long width2,
  563.     unsigned long height2,        
  564.     unsigned long angle,
  565.     unsigned long zoom )
  566. {
  567.     long            x,y;                            // loop variables
  568.     register unsigned long    *src,*dst;                // image pointers
  569.     unsigned long    stride;                            // add to go to next row
  570.     long            half_width,half_height;            // half of destination
  571.     long            start_u,start_v;                // starting texel
  572.     long            sint,cost;                        // sine and cosine
  573.     unsigned long    u,v,ul,vl;                        // texel, and fixed point texel
  574.     long            is_shift,shift_x,shift_y;        // shift instead of multiply
  575.  
  576.         /* normalize angle and zoom */
  577.     while (angle < 0)        angle += 360;
  578.     while (angle >= 360)    angle -= 360;
  579.  
  580.         /* get look-up values */
  581.     zoom >>= 8;
  582.     sint = (sintable[angle] * (long) zoom) >> 8;
  583.     cost = (costable[angle] * (long) zoom) >> 8;
  584.     
  585.     half_width = width2 >> 1;
  586.     half_height = height2 >> 1;
  587.  
  588.         /* get texture starting values (rotate around center) */
  589.     start_u = (width1 >> 1) << 16;
  590.     start_v = (height1 >> 1) << 16;
  591.     start_u -= cost * half_width - sint * half_height;
  592.     start_v -= sint * half_width + cost * half_height;
  593.     
  594.         /* init pointers & counters */
  595.     src = (unsigned long *) source;
  596.     dst = (unsigned long *) dest;
  597.     stride = (dstBytes - width2);
  598.     
  599.         /* is texture a multiple of 2 ? */
  600.     is_shift = log2(width1,&shift_x) && log2(height1,&shift_y);
  601.  
  602.     y = height2;
  603.     
  604.     if (is_shift)
  605.     {
  606.         do
  607.         {
  608.             ul = start_u;    vl = start_v;
  609.  
  610.             for (x = 0; x < width2; x++)
  611.             {    
  612.                 u = ul >> 16;    v = vl >> 16;    
  613.                 
  614.                 if (u >= 0 && u < width1 && v > 0 && v < height1 )
  615.                     *dst++ = src[(v << shift_x) + u];
  616.                 else
  617.                     ++dst;
  618.             
  619.                 ul += horiz_delta_u;    vl += horiz_delta_v;
  620.             }
  621.             
  622.             start_u += vert_delta_u;    start_v += vert_delta_v;
  623.             
  624.             dst += stride;
  625.         
  626.         } while (--y);
  627.     }
  628.     else
  629.     {
  630.         do
  631.         {
  632.             ul = start_u;    vl = start_v;
  633.  
  634.             for (x = 0; x < width2; x++)
  635.             {    
  636.                 u = ul >> 16;    v = vl >> 16;    
  637.                 
  638.                 if (u >= 0 && u < width1 && v >= 0 && v < height1 )
  639.                     *dst++ = src[(v * srcBytes) + u];
  640.                 else
  641.                     ++dst;
  642.             
  643.                 ul += horiz_delta_u;    vl += horiz_delta_v;
  644.             }
  645.             
  646.             start_u += vert_delta_u;    start_v += vert_delta_v;
  647.             
  648.             dst += stride;
  649.         
  650.         } while (--y);
  651.         
  652.     }
  653.  
  654. }
  655.  
  656. void BlitPixieMaskRotoZoom32Bit(
  657.     unsigned long *source,
  658.     unsigned long *dest,
  659.     unsigned long *maskAddr,
  660.     unsigned long srcBytes,
  661.     unsigned long dstBytes,
  662.     unsigned long width1,
  663.     unsigned long height1,        
  664.     unsigned long width2,
  665.     unsigned long height2,        
  666.     unsigned long angle,
  667.     unsigned long zoom )
  668. {
  669.     long            x,y;                            // loop variables
  670.     register unsigned long    *src,*dst,*mask;        // image pointers
  671.     unsigned long    stride;                            // add to go to next row
  672.     long            half_width,half_height;            // half of destination
  673.     long            start_u,start_v;                // starting texel
  674.     long            sint,cost;                        // sine and cosine
  675.     unsigned long    u,v,ul,vl;                        // texel, and fixed point texel
  676.     long            is_shift,shift_x,shift_y;        // shift instead of multiply
  677.  
  678.         /* normalize angle and zoom */
  679.     while (angle < 0)        angle += 360;
  680.     while (angle >= 360)    angle -= 360;
  681.  
  682.         /* get look-up values */
  683.     zoom >>= 8;
  684.     sint = (sintable[angle] * (long) zoom) >> 8;
  685.     cost = (costable[angle] * (long) zoom) >> 8;
  686.     
  687.     half_width = width2 >> 1;
  688.     half_height = height2 >> 1;
  689.  
  690.         /* get texture starting values (rotate around center) */
  691.     start_u = (width1 >> 1) << 16;
  692.     start_v = (height1 >> 1) << 16;
  693.     start_u -= cost * half_width - sint * half_height;
  694.     start_v -= sint * half_width + cost * half_height;
  695.     
  696.         /* init pointers & counters */
  697.     src = (unsigned long *) source;
  698.     mask = (unsigned long *) maskAddr;
  699.     dst = (unsigned long *) dest;
  700.     stride = (dstBytes - width2);
  701.     
  702.         /* is texture a multiple of 2 ? */
  703.     is_shift = log2(width1,&shift_x) && log2(height1,&shift_y);
  704.  
  705.     y = height2;
  706.     
  707.     if (is_shift)
  708.     {
  709.         do
  710.         {
  711.             ul = start_u;    vl = start_v;
  712.  
  713.             for (x = 0; x < width2; x++)
  714.             {    
  715.                 u = ul >> 16;    v = vl >> 16;    
  716.                 
  717.                 if (u >= 0 && u < width1 && v > 0 && v < height1 )
  718.                 {
  719.                     if ( mask[(v << shift_x) + u] == 0 )
  720.                         *dst++ = src[(v << shift_x) + u];
  721.                     else
  722.                         ++dst;
  723.                 }
  724.                 else
  725.                     ++dst;
  726.             
  727.                 ul += horiz_delta_u;    vl += horiz_delta_v;
  728.             }
  729.             
  730.             start_u += vert_delta_u;    start_v += vert_delta_v;
  731.             
  732.             dst += stride;
  733.         
  734.         } while (--y);
  735.     }
  736.     else
  737.     {
  738.         do
  739.         {
  740.             ul = start_u;    vl = start_v;
  741.  
  742.             for (x = 0; x < width2; x++)
  743.             {    
  744.                 u = ul >> 16;    v = vl >> 16;    
  745.                 
  746.                 if (u >= 0 && u < width1 && v >= 0 && v < height1 )
  747.                 {
  748.                     if ( mask[(v * srcBytes) + u] == 0 )
  749.                         *dst++ = src[(v * srcBytes) + u];
  750.                     else
  751.                         ++dst;
  752.                 }
  753.                 else
  754.                     ++dst;
  755.             
  756.                 ul += horiz_delta_u;    vl += horiz_delta_v;
  757.             }
  758.             
  759.             start_u += vert_delta_u;    start_v += vert_delta_v;
  760.             
  761.             dst += stride;
  762.         
  763.         } while (--y);
  764.     }
  765.  
  766. }
  767.  
  768. #endif